<template>
  <div class="app-container">
    <el-row :gutter="20">
      <!-- 左侧表单区域 -->
      <el-col :span="10">
        <el-card>
          <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
            <el-form-item label="选择模板" prop="execTemplateId">
              <el-select
                v-model="form.execTemplateId"
                placeholder="请选择模板"
                style="width: 100%"
                @change="onTemplateChange"
              >
                <el-option
                  v-for="tpl in templateData"
                  :key="tpl.id"
                  :label="tpl.name"
                  :value="tpl.id"
                />
              </el-select>
            </el-form-item>
            <el-form-item label="主机组" prop="hostGroupId">
              <el-tree-select
                v-model="form.hostGroupId"
                :data="groupTree"
                check-strictly
                :props="{ label: 'name', children: 'children' }"
                :render-after-expand="false"
                placeholder="请选择主机组"
                style="width: 100%"
              />
            </el-form-item>
            <el-form-item label="超时时间" prop="timeout">
              <el-input v-model="form.timeout" placeholder="请输入超时时间"/>
            </el-form-item>
            <el-form-item label="备注说明" prop="description">
              <el-input v-model="form.description" type="textarea" :rows="2" placeholder="请输入描述" maxlength="255" show-word-limit />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="submitExec">执行</el-button>
            </el-form-item>
          </el-form>
        </el-card>
         <!-- 服务器执行进度 -->
        <el-card class="server-card" v-if="serverProgress.length > 0">
          <div class="server-progress-list">服务器执行进度
            <div v-for="host in serverProgress" :key="host.hostId" class="server-item">
              <span class="server-name">{{ host.hostName }}</span>
              <span class="server-address">{{ host.hostAddress }}</span>
              <el-tag :type="getStatusType(host.status)" size="small">
                {{ getStatusText(host.status) }}
              </el-tag>
              <!-- <span class="server-address">耗时:{{ host.timeout }}ms</span> -->
            </div>
          </div>
        </el-card>
      </el-col>

      <!-- 右侧命令显示区域 -->
      <el-col :span="14">
        <el-card>
          <div class="command-title">执行命令</div>
          <el-input
            v-model="form.command"
            type="textarea"
            :rows="10"
            class="shell-input"
            placeholder="请输入shell命令"
          />
          <!-- 参数展示区域 -->
          <template v-if="selectedTemplateParams.length">
            <el-divider border-style="dashed" style="margin: 18px 0 10px 0;">命令参数</el-divider>
            <div v-for="(param, idx) in selectedTemplateParams" :key="idx" class="param-row">
              <span class="param-label">{{ param.key || param.name }}：</span>
              <el-input 
                v-model="param.value" 
                class="param-input" 
                :placeholder="`请输入${param.key || param.name}`"
                @input="updateCommandWithParams"
              disabled/>
            </div>
          </template>
        </el-card>

       
      </el-col>
    </el-row>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { listGroup } from "@/api/os/group"
import { listTemplate } from "@/api/exec/template"
import { execCommand, getExecProgress } from "@/api/exec/command"

const selectedTemplateParams = ref([])
const form = reactive({
  execTemplateId: '',
  hostGroupId: '',
  timeout: '',
  description: '',
  command: ''
})
const rules = {
  execTemplateId: [{ required: true, message: '请选择模板', trigger: 'change' }],
  hostGroupId: [{ required: true, message: '请选择主机组', trigger: 'change' }],
  command: [{ required: true, message: 'shell命令不能为空', trigger: 'blur' }]
}
const templateData = ref([])
const groupTree = ref([])
const serverProgress = ref([])
const progressInterval = ref(null)

// 加载模板
const getTemplateCommand = () => {
  listTemplate().then(res => {
    if (res.code === 200) templateData.value = res.rows || res.data || []
  })
}
// 获取主机组树
const getGroupTree = () => {
  listGroup().then(response => {
    if (response.code === 200) {
      groupTree.value = response.data
      // 确保数据结构正确，el-tree-select 需要正确的 value 和 label
      const processTreeData = (nodes) => {
        return nodes.map(node => ({
          ...node,
          value: node.id, // 用于 v-model 绑定的值
          label: node.name, // 用于显示的标签
          children: node.children ? processTreeData(node.children) : []
        }))
      }
      groupTree.value = processTreeData(response.data)
    } else {
      ElMessage.error("获取分组列表失败")
    }
  }).catch(error => {
    console.error("获取分组列表失败:", error)
    ElMessage.error("获取分组列表失败")
  })
}


// 选择模板时自动填充命令
const onTemplateChange = (id) => {
  const tpl = templateData.value.find(t => t.id === id)
  if (tpl) {
    form.command = tpl.command
    // 解析参数
    try {
      selectedTemplateParams.value = tpl.parameterSchema ? JSON.parse(tpl.parameterSchema) : []
      // 初始化参数值
      selectedTemplateParams.value.forEach(param => {
        if (!param.value) param.value = ''
      })
    } catch {
      selectedTemplateParams.value = []
    }
  } else {
    selectedTemplateParams.value = []
  }
}

// 根据参数更新命令
const updateCommandWithParams = () => {
  if (!form.execTemplateId) return
  
  const tpl = templateData.value.find(t => t.id === form.execTemplateId)
  if (!tpl) return
  
  let command = tpl.command
  selectedTemplateParams.value.forEach(param => {
    const placeholder = `\${${param.key || param.name}}`
    command = command.replace(new RegExp(placeholder, 'g'), param.value || '')
  })
  
  form.command = command
}

// 提交并执行
const submitExec = () => {
  if (!form.command) {
    ElMessage.error('请输入命令')
    return
  }
    // 准备提交数据，包含参数值
  const submitData = {
    ...form,
    parameterSchema: JSON.stringify(selectedTemplateParams._rawValue)
  }
  
  execCommand(submitData).then(res => {
    if (res.code === 200) {
      ElMessage.success('命令已提交，正在执行')
      startProgressPolling(res.data)
    }else {
      ElMessage.error(res.message || '命令执行失败')
    }
  })
}

// 轮询服务器执行进度
const startProgressPolling = (taskId) => {
  if (progressInterval.value) clearInterval(progressInterval.value)
  progressInterval.value = setInterval(() => {
    getExecProgress(taskId).then(res => {
      if (res.code === 200) {
        debugger
        serverProgress.value = res.data || []
        // 判断是否全部完成
        if (serverProgress.value.every(h => ['finished', 'failed'].includes(h.status))) {
          clearInterval(progressInterval.value)
        }
      }
    })
  }, 2000)
}

// 状态映射
const getStatusText = (status) => {
  const map = { waiting: '等待中', uploading: '处理中', finished: '已完成', failed: '失败' }
  return map[status] || status
}
const getStatusType = (status) => {
  const map = { waiting: 'info', uploading: 'warning', finished: 'success', failed: 'danger' }
  return map[status] || ''
}

onMounted(() => {
  getTemplateCommand()
  getGroupTree()
})
</script>

<style scoped>
.command-area {
  background: #222;
  color: #fff;
  border-radius: 6px;
  padding: 24px;
  margin-bottom: 24px;
  min-height: 260px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.command-title {
  color: #333;
  font-size: 16px;
  font-weight: bold;
  margin-bottom: 12px;
  align-self: flex-start;
}
.shell-input textarea {
  background-color: #222 !important;
  color: #fff !important;
  font-family: "Fira Mono", "Consolas", "Menlo", monospace;
  font-size: 15px;
  border-radius: 4px;
  min-height: 180px;
  width: 100%;
}
:deep(.shell-input textarea) {
  background: #222 !important;
  color: #fff !important;
}


.server-card {
  margin-top: 20px;
}
.server-item {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px solid #333;
}
.server-name {
  font-weight: 600;
  color: #333;
}
.server-address {
  color: #606266;
  font-size: 13px;
}
.param-row {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
}
.param-label {
  width: 100px;
  text-align: right;
  padding-right: 12px;
  color: #606266;
}
.param-input {
  flex: 1;
}
</style>